<?php

namespace Wintel\RestBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class CtiController
 *
 * @package Wintel\RestBundle\Controller
 */
class CtiController extends Controller
{
    /**
     * web800呼叫
     *
     * @param Request $request The Request Object
     *
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     */
    public function webcallAction(Request $request)
    {
        $caller = $request->get("caller", 0);
        $called = $request->get("called", 0);
        $vcc_id = $request->get("vcc_id", 0);
        $vcc_code = $request->get("vcc_code", 0);
        $timeout = $request->get("timeout", 50);
        $display_caller = $request->get("display_caller", '');
        $display_called = $request->get("display_called", '');
        $if_transmit = $request->get("if_transmit", 0);
        $is_showcaller= $request->get("is_showcaller", 0);
        $transfer_sound = $request->get("transfer_sound", '');
        $transfer_sound = str_ireplace('.wav', '', $transfer_sound);
        $display_caller = $if_transmit == 1 ? $called : $display_caller;
        $display_called = $is_showcaller == 1 ? $caller : $display_called;
        /** @var \Doctrine\DBAL\Connection $conn */
        $conn = $this->get('doctrine.dbal.default_connection');

        if (empty($vcc_id)) {
            $msg = $vcc_id = $this->container->get('validator.custom')->checkVccCode($vcc_code);
            if (!empty($msg) && is_array($msg)) {
                return new JsonResponse($msg);
            }
        } else {
            if (!is_numeric($vcc_id)) {
                $ret = array(
                    'code' => 408,
                    'message' => '企业ID包含非数字字符',
                );
                return new JsonResponse($ret);
            }
            //判断企业ID 是否存在；
            $vcc_code = $conn->fetchColumn(
                "SELECT vcc_code FROM cc_ccods WHERE status=1 AND vcc_id = :vcc_id",
                array('vcc_id' => $vcc_id)
            );
            if (empty($vcc_code)) {
                $ret = array(
                    'code' => 409,
                    'message' => '企业ID不存在',
                );
                return new JsonResponse($ret);
            }
        }
        $user = $this->getUser();
        if (empty($user) || $user->getVccId() != $vcc_id) {
            return new JsonResponse(array('code'=>410, 'message'=>'未验证通过或企业信息填写错误'));
        }
        if (empty($caller)) {
            $ret = array(
                'code' => 403,
                'message' => '主叫号码为空',
            );
            return new JsonResponse($ret);
        }
        if ($this->verifyPhoneIsValid($caller) === false) {
            $ret = array(
                'code' => 406,
                'message' => '主叫号码格式不正确',
            );
            return new JsonResponse($ret);
        }
        if (empty($called)) {
            $ret = array(
                'code' => 404,
                'message' => '被叫号码为空',
            );
            return new JsonResponse($ret);
        }
        if ($this->verifyPhoneIsValid($called) === false) {
            $ret = array(
                'code' => 407,
                'message' => '被叫号码格式不正确',
            );
            return new JsonResponse($ret);
        }

        $numbers = $conn->fetchAll(
            "SELECT phone,phone400 FROM cc_phone400s WHERE vcc_id = :vcc_id ", array('vcc_id'=>$vcc_id)
        );
        $vaildNum = array();
        foreach ($numbers as $num) {
            $vaildNum[] = $num['phone'];
            $vaildNum[] = $num['phone400'];
        }
        $vaildNum = array_unique($vaildNum);
        if ((!in_array($display_called, $vaildNum) && $is_showcaller != 1) || (!in_array($display_caller, $vaildNum) && $if_transmit != 1)) {
            $ret = array(
                'code' => 411,
                'message' => '呼叫主叫号码显示或者呼叫被叫号码显示 不存在,请统一填写你们的400号码',
            );
            return new JsonResponse($ret);
        }
        //发送socket数据
        $logger = $this->get('logger');
        $address =$this->container->getParameter('win_ip');
        $port = $this->container->getParameter('win_socket_port');
        $caller = $this->checkPhoneArea($caller);
        $called = $this->checkPhoneArea($called);
        $socket_command = "makecall($vcc_id,$display_caller,$caller,$timeout,0,1,callback_haodai,ivr_in,transoutpho=$called|transcaller=$display_called|transfer_sound=$transfer_sound)";
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($socket === false) {
            $errorCode = socket_last_error();
            $errorMsg = socket_strerror($errorCode);
            $logger->debug('无法创建socket：【'.$errorCode.'】'.$errorMsg);
            $ret = array(
                'code' => 405,
                'message' => '呼叫失败',
            );
            return new JsonResponse($ret);
        }

        $res = socket_connect($socket, $address, $port);
        //连接失败
        if ($res === false) {
            $errorCode = socket_last_error();
            $errorMsg = socket_strerror($errorCode);
            $logger->debug('socket无法连接到【'.$address.':'.$port.'】：【'.$errorCode.'】'.$errorMsg);

            $ret = array(
                'code' => 405,
                'message' => '呼叫失败',
            );
            return new JsonResponse($ret);
        }

        $socket_command .= "\r\n\r\n";
        $res = socket_write($socket, $socket_command, strlen($socket_command));

        //发送数据失败
        if ($res === false) {
            $errorCode = socket_last_error();
            $errorMsg = socket_strerror($errorCode);
            $logger->debug('socket发送数据失败：【'.$errorCode.'】'.$errorMsg);

            $ret = array(
                'code' => 405,
                'message' => '呼叫失败',
            );
            return new JsonResponse($ret);
        }

        $responce = socket_read($socket, 1024);

        if ($responce === false) {
            $errorCode = socket_last_error();
            $errorMsg = socket_strerror($errorCode);
            $logger->debug('socket读取数据失败：【'.$errorCode.'】'.$errorMsg);

            $ret = array(
                'code' => 405,
                'message' => '呼叫失败',
            );
            return new JsonResponse($ret);
        }

        //呼叫成功
        if (strstr($responce, 'Success')) {
            $responce = str_replace("\r\n", '', $responce);
            $logger->debug($responce);
            //呼叫成功返回 callid;
            $callid = trim(substr($responce, strpos($responce, 'CallID:')+7));
            $ret = array(
                'code' => 200,
                'message' => 'ok',
                'callid' => $callid,
            );

            return new JsonResponse($ret);
        } else {
            $responce = str_replace("\r\n", '', $responce);
            $logger->debug($responce);
            $ret = array(
                'code' => 405,
                'message' => '呼叫失败',
            );
            return new JsonResponse($ret);
        }
    }

    /**
     * @param $phone
     * @return int|string
     *
     */
    public function checkPhoneArea($phone)
    {
        $stphone = $phone;
        if (strlen($phone) == 12 && '0' == substr($phone, 0, 1)) {
            $stphone = substr($phone, 1);
        }
        $line_code =  $this->container->getParameter('local_code');
        if (preg_match("/^1[3-9]\\d{9}$/", $stphone)) {//是手机号码
            //获取区号
            /** @var \Doctrine\DBAL\Connection $conn */
            $conn = $this->get('doctrine.dbal.default_connection');
            $cpre = substr($stphone, 0, 7);
            //查出号码归属地
            $code = $conn->fetchColumn(
                "select code from cc_callerloc where num = :num ",
                array('num'=>$cpre)
            );

            if (!empty($code)) {
                return '0'.$stphone; //没有找到
            } else {
                //廊坊手机去0
                if ($line_code == $code) {
                    return $stphone;
                } else {//非廊坊手机加0
                    return '0'.$stphone;
                }
            }
        }
        if ($line_code == substr($phone, 0, 4)) {
            $sphone = substr($phone, 4);
            return $sphone;
        } else {
            return $phone;
        }
    }

    /**
     * 验证是否是正常的手机号码或固话
     *
     * @param string $phone
     * @return bool
     */
    public function verifyPhoneIsValid($phone)
    {
        $reg = '/^0?1[3-9]\d{9}$|^0\d{3}\d{8}$|^0\d{2}\d{8}$|^0\d{3}\d{7}|^400\d{7}$/';

        if (preg_match($reg, $phone)) {
            return true;
        } else {
            return false;
        }
    }
}
